/*
 * HaikuOS null驱动示例
 * 这是一个简单的字符设备驱动，它实现了基本的文件操作接口
 * 但实际上不执行任何实质性的IO操作
 */

#include <Drivers.h>
#include <Errors.h>
#include <string.h>

#define DEVICE_NAME "null"

// 驱动版本号
const char* api_version = "1.0";

// 设备私有数据
struct device_private {
    // 在这个简单驱动中不需要额外的私有数据
};

// 设备打开函数
error_code null_open(struct file_operations* file_ops) {
    // 分配并初始化设备私有数据
    struct device_private* private_data = malloc(sizeof(struct device_private));
    if (!private_data) {
        return B_NO_MEMORY;
    }
    
    // 存储私有数据
    file_ops->cookie = private_data;
    
    return B_OK;
}

// 设备关闭函数
error_code null_close(struct file_operations* file_ops) {
    // 释放设备私有数据
    if (file_ops->cookie) {
        free(file_ops->cookie);
        file_ops->cookie = NULL;
    }
    
    return B_OK;
}

// 设备IO控制函数
error_code null_ioctl(struct file_operations* file_ops, uint32 op, void* buffer, size_t length) {
    // 这个简单驱动不支持任何IO控制操作
    return B_UNSUPPORTED;
}

// 设备读取函数
size_t null_read(struct file_operations* file_ops, void* buffer, size_t length) {
    // null驱动的读取总是返回0字节
    return 0;
}

// 设备写入函数
size_t null_write(struct file_operations* file_ops, const void* buffer, size_t length) {
    // null驱动的写入总是返回请求的长度，但实际上不做任何操作
    return length;
}

// 设备查找函数
error_code find_device(const char* name, struct driver_module_info* info, void** cookie) {
    // 只支持null设备
    if (strcmp(name, DEVICE_NAME) != 0) {
        return B_ERROR;
    }
    
    *cookie = NULL;
    return B_OK;
}

// 硬件初始化函数
error_code init_hardware(void) {
    // 这个驱动不需要特定的硬件初始化
    return B_OK;
}

// 设备发布函数
error_code publish_devices(void) {
    // 在设备管理器中发布null设备
    return publish_driver_device(DEVICE_NAME, NULL);
}

// 驱动初始化函数
error_code init_driver(void) {
    // 驱动初始化成功
    return B_OK;
}

// 驱动卸载函数
error_code uninit_driver(void) {
    // 驱动卸载成功
    return B_OK;
}

// 设备操作钩子
struct device_hooks device_hooks = {
    .open = null_open,
    .close = null_close,
    .free = NULL,
    .read = null_read,
    .write = null_write,
    .ioctl = null_ioctl,
    .select = NULL,
};